package com.gagakuai.engine.impl.command;

import com.gagakuai.engine.exception.ActivitiObjectNotFoundException;
import com.gagakuai.engine.impl.interceptor.Command;
import com.gagakuai.engine.impl.interceptor.CommandContext;
import com.gagakuai.engine.impl.persistence.deploy.DeploymentManager;
import com.gagakuai.engine.impl.persistence.entity.ExecutionEntity;
import com.gagakuai.engine.impl.persistence.entity.ProcessDefinitionEntity;
import com.gagakuai.engine.impl.pvm.PvmProcessInstance;
import com.gagakuai.engine.impl.runtime.ProcessInstanceBuilderImpl;
import com.gagakuai.engine.repository.ProcessDefinition;
import com.gagakuai.engine.runtime.ProcessInstance;

import java.io.Serializable;
import java.util.Map;

/**
 * @program: common-starters
 * @description: 流程实列启动命令对象:使用了智能命令：将命令（请求）和实现合并
 * @author: houhong
 * @create: 2023-01-02 14:53
 **/
public class StartProcessInstanceCmd<T> implements Command<ProcessInstance>, Serializable {


    private static final long serialVersionUID = -8648972188574374980L;

    /**
     * 流程定义key
     **/
    protected String processDefinitionKey;
    /**
     * 流程定义id
     **/
    protected String processDefinitionId;
    /**
     * 执行的流转变量
     **/
    protected Map<String, Object> variables;
    /**
     * 业务key
     **/
    protected String businessKey;
    /**
     * 租户id
     **/
    protected String tenantId;
    /**
     * 流程实列名
     **/
    protected String processInstanceName;

    public StartProcessInstanceCmd(String processDefinitionKey, String processDefinitionId, String businessKey, Map<String, Object> variables) {
        this.processDefinitionKey = processDefinitionKey;
        this.processDefinitionId = processDefinitionId;
        this.businessKey = businessKey;
        this.variables = variables;
    }

    public StartProcessInstanceCmd(String processDefinitionKey, String processDefinitionId,
                                   String businessKey, Map<String, Object> variables, String tenantId) {
        this(processDefinitionKey, processDefinitionId, businessKey, variables);
        this.tenantId = tenantId;
    }

    public StartProcessInstanceCmd(ProcessInstanceBuilderImpl processInstanceBuilder) {
        this(processInstanceBuilder.getProcessDefinitionKey(), processInstanceBuilder.getProcessDefinitionId(),
                processInstanceBuilder.getBusinessKey(), processInstanceBuilder.getVariables(), processInstanceBuilder.getTenantId());
        this.processInstanceName = processInstanceBuilder.getProcessInstanceName();
    }

    @Override
    public ProcessInstance execute(CommandContext commandContext) {

        //// TODO: 2023/1/2
        DeploymentManager deploymentManager = commandContext.getProcessEngineConfiguration()
                .getDeploymentManager();

        //存储所有的activitiy和tansistionImpl
        ProcessDefinitionEntity processDefinitionEntity = null;

        if (processDefinitionId != null) {
            //拿到实体
            processDefinitionEntity = deploymentManager.findDeployedProcessDefinitionById(processDefinitionId);
            if (processDefinitionEntity == null) {
                throw new ActivitiObjectNotFoundException("No process definition found for id = '" + processDefinitionId + "'", ProcessDefinition.class);
            }
        }
        //// TODO: 2023/1/2  后续策略

        //判断流程是否挂起

        //开始流程 重要
        ExecutionEntity processInstance = processDefinitionEntity.createProcessInstance();

        //设置变量
        initializeVariables(processInstance);
        //启动流程
        processInstance.start();


        return processInstance;
    }

    protected void initializeVariables(ExecutionEntity processInstance) {
        if (variables != null) {
            //processInstance.setVariables(variables);
        }
    }
}